package thread.multi.comuni;

//测试：生产者消费者问题-->信号灯法

//成员：后宫们，后宫王，sex前戏，床
/**
 * 将产品置留标志位，通过判断标志位，达到线程间的通信
 * 1.线程开启后，线程都在执行
 * 2.当消费者线程执行时(后宫王准备sex时)，如果标志位为假(后宫们未做好前戏)，消费者线程等待(后宫王需要等待)，生产者线程继续(后宫们进行前戏)
 * 3.当生产者线程执行时(后宫们准备前戏)，如果标志位为真(床已被使用，存在后宫做好前戏)，生产者线程等待(其它后宫先等待)，消费者线程继续(后宫王sex)
 * 4.否则，当生产者生产后唤醒消费者(一名后宫前戏完成，上床躺好，叫后宫王sex)，消费者消费后唤醒生产者(后宫王sex完成，床位空出，叫后宫们前戏)
 * 其的根本逻辑在于，不存在一种状态，使得消费者和生产者同时等待
 */
public class PCpv {

    public static void main(String[] args) {
        Bed bed = new Bed();
        String[] list = new String[]{"安静姐姐", "淘气妹妹", "温婉红颜", "巨乳萝莉"};
        new Harem(bed,list).start();
        new Boy(bed).start();
    }
}

class Harem extends Thread {
    public Bed bed;
    public String[] list = null;

    public Harem(Bed bed,String[] list) {
        this.bed = bed;
        this.list = list;
    }

    @Override
    public void run() {
        for (int i = 0; i < 8; i++) {
            this.bed.ready(list[i%4]);
        }
    }
}

class Boy extends Thread {
    public Bed bed;

    public Boy(Bed bed) {
        this.bed = bed;
    }

    @Override
    public void run() {
        for (int i = 0; i < 8; i++) {
            bed.sex();
        }
    }
}

class Bed {
    //Harem准备，Boy等待
    //Boy开始，Harem等待
    String girl;
    boolean flag = true;

    //整理床铺
    public synchronized void ready(String name) {
        if (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //通知后宫王
        this.girl = name;
        System.out.println(girl+"后宫准备好了");
        this.notifyAll();
        this.flag = !this.flag;
    }

    public synchronized void sex() {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //通知下一位后宫
        System.out.println("后宫王大战"+girl);
        this.notifyAll();
        this.flag = !this.flag;
    }
}